//
//  CachableSliderView.swift
//  GhostWorld
//
//  Created by Kam on 2018/4/7.
//  Copyright © 2018 LKGood. All rights reserved.
//

import UIKit
import SnapKit

protocol SliderViewDelegate {
  func sliderView(_ sliderView: SliderView, draggingProgress: Float)
  func sliderView(_ sliderView: SliderView, didEndTouchWithProgress: Float)
}

@IBDesignable class SliderView: UIView {

  // MARK: - Private vars
  
  private var bgBar = UIView()
  private var cacheBar = UIView()
  private var progressBar = UIView()
  private var thumb = UIView()
  private var thumbImageView = UIImageView(image: UIImage(named: "SliderThumb"))
  
  private var cacheWidthConstraint: Constraint? = nil
  private var progressWidthConstraint: Constraint? = nil
  
  private var canDrag = false
  private var internalProgress: Float = 0
  
  // MARK: - Private methods
  
  private func setup() {
    isMultipleTouchEnabled = false
    backgroundColor = .clear
    
    bgBar.isUserInteractionEnabled = false
    addSubview(bgBar)
    bgBar.snp.makeConstraints { maker in
      maker.height.equalTo(2)
      maker.centerY.equalTo(self.snp.centerY)
      maker.leading.trailing.equalTo(0)
    }
    bgBar.backgroundColor = bgBarColor
    
    cacheBar.isUserInteractionEnabled = false
    addSubview(cacheBar)
    setProgressConstrains(bar: cacheBar, percentage: 0)
    cacheBar.backgroundColor = cacheBarColor
    
    progressBar.isUserInteractionEnabled = false
    addSubview(progressBar)
    setProgressConstrains(bar: progressBar, percentage: 0)
    progressBar.backgroundColor = progressBarColor
    
    thumb.isUserInteractionEnabled = false
    addSubview(thumb)
    thumb.snp.makeConstraints { maker in
      maker.width.height.equalTo(60)
      maker.centerY.equalTo(progressBar)
      maker.centerX.equalTo(progressBar.snp.trailing)
    }
    thumb.backgroundColor = .clear
    
    thumb.addSubview(thumbImageView)
    setThumbImageConstrains(side: 15)
  }
  
  private func setThumbImageConstrains(side: Float) {
    thumbImageView.snp.remakeConstraints { maker in
      maker.center.equalTo(thumb)
      maker.width.height.equalTo(side)
    }
  }
  
  private func setProgressConstrains(bar: UIView, percentage: Float) {
    bar.snp.remakeConstraints { maker in
      maker.height.equalTo(2)
      maker.centerY.equalTo(self.snp.centerY)
      maker.leading.equalTo(0)
      if percentage == 0 {
        maker.width.equalTo(0)
      } else if percentage == 1 {
        maker.width.equalTo(self)
      } else {
        maker.width.equalTo(self).multipliedBy(percentage)
      }
    }
  }
  
  private func amplifyThumbImage() {
    UIView.animate(withDuration: 0.3, delay: 0, options: [.beginFromCurrentState], animations: {
      self.setThumbImageConstrains(side: 30)
      self.layoutIfNeeded()
    }, completion: nil)
  }
  
  private func shrinkThumbImage() {
    UIView.animate(withDuration: 0.3, delay: 0, options: [.beginFromCurrentState], animations: {
      self.setThumbImageConstrains(side: 15)
      self.layoutIfNeeded()
    }, completion: nil)
  }
  
  // MARK: - Public vars
  
  @IBInspectable var bgBarColor: UIColor = UIColor(fromRGB: 0x404040) {
    didSet {
      bgBar.backgroundColor = bgBarColor
    }
  }
  
  @IBInspectable var cacheBarColor: UIColor = UIColor(fromRGB: 0x787878) {
    didSet {
      cacheBar.backgroundColor = cacheBarColor
    }
  }
  
  @IBInspectable var progressBarColor: UIColor = UIColor(fromRGB: 0xF20B1D) {
    didSet {
      progressBar.backgroundColor = progressBarColor
    }
  }
  
  @IBInspectable var progress: Float = 0.5 {
    didSet {
      if progressBar.superview == self {
        if !canDrag {
          setProgressConstrains(bar: progressBar, percentage: progress)
        }
      }
    }
  }
  
  @IBInspectable var cacheProgress: Float = 0 {
    didSet {
      if cacheBar.superview == self {
        setProgressConstrains(bar: cacheBar, percentage: cacheProgress)
      }
    }
  }
  
  // MARK: - Lifecycle
  
  override var frame: CGRect {
    didSet {
      
    }
  }
  
  override func layoutSubviews() {
    super.layoutSubviews()
    
  }
  
  //  override public init(frame: CGRect) {
  //    super.init(frame: frame)
  //    setup()
  //  }
  //
  //  required public init?(coder aDecoder: NSCoder) {
  //    super.init(coder: aDecoder)
  //    setup()
  //  }
  
  override func awakeFromNib() {
    super.awakeFromNib()
    setup()
  }
  
  override func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()
    setup()
  }
  
  // MARK: - Public vars
  
  var delegate: SliderViewDelegate?
  
  // MARK: - Touches
  
  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
      let pointX = touch.location(in: self).x
      internalProgress = Float(pointX / width)
      internalProgress = max(0, internalProgress)
      internalProgress = min(1, internalProgress)
      setProgressConstrains(bar: progressBar, percentage: internalProgress)
//      if thumb.frame.contains(point) {
      amplifyThumbImage()
      canDrag = true
//      }
    }
  }
  
  override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if canDrag {
      if let touch = touches.first {
        let pointX = touch.location(in: self).x
        internalProgress = Float(pointX / width)
        internalProgress = max(0, internalProgress)
        internalProgress = min(1, internalProgress)
        setProgressConstrains(bar: progressBar, percentage: internalProgress)
        delegate?.sliderView(self, draggingProgress: internalProgress)
      }
    }
  }
  
  private func handleTouchEnd() {
    shrinkThumbImage()
    progress = internalProgress
    delegate?.sliderView(self, didEndTouchWithProgress: progress)
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
      self.canDrag = false
    }
  }
  
  override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    handleTouchEnd()
  }
  
  override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
    handleTouchEnd()
  }
}
